//
//  RainBow.swift
//  AModule
//
//  Created by sk on 2021/11/7.
//

import Foundation
import UIKit

public protocol RainBowLifecycle {
    func applicationDidBecomeActive(_ application: UIApplication)
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
}

open class RainBow :  RainBowLifecycle {
    
    private init() {}
    public static let shared: RainBow = RainBow()
    fileprivate var providers:[ModuleProvider]  = [ModuleProvider]()
    fileprivate var providerTypes:[ModuleProvider.Type] = [ModuleProvider.Type]()
    private var urlCache: [String: ViewControllerConvertable] = [String: ViewControllerConvertable]()
    public func register(provider: ModuleProvider) {
        providers.append( provider)
    }
    
    public func register( routers:[String: ViewControllerConvertable]) {
        for router in routers {
            if  !urlCache.contains(where: { it in
                router.key == it.key
            }) {
                urlCache[router.key] = router.value
            }
        }
    }
    
    
    func route(url: String, params:[AnyHashable: Any]?) -> (url: String, params: [AnyHashable: Any]?, controller: ViewControllerConvertable)? {
        if let router = urlCache[url] {
            return (url, params, router)
        }
        for provider in providers {
            for item in provider.moduleRouters {
                if item.key == url {
                    urlCache[url] = item.value
                    break
                }
            }
        }
        if let router = urlCache[url] {
            return (url, params, router)
        }
        return nil
    }
}


extension RainBowLifecycle where Self: RainBow{
    public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {
        providers.forEach { provider in
            _ =  provider.application(application, didFinishLaunchingWithOptions: launchOptions)
        }
        return true
    }
    
    public  func applicationDidBecomeActive(_ application: UIApplication) {
        providers.forEach { provider in
            provider.applicationDidBecomeActive(application)
        }
    }
    
}


